home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
COMBIOS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-22
|
5KB
|
178 lines
/* support for serial communication using COMBIOS/MBBIOS/FOSSIL on the IBM-PC */
#include <stdio.h>
#include "global.h"
#include "asy.h"
#include "combios.h"
#include "slip.h"
#include "iface.h"
struct com com[ASY_MAX]; /* info about the COMBIOS ports */
extern unsigned int combios(); /* INT14 access routine */
/* args are AX and DX */
static char badspeed[] = "Bad speed on COM\n";
/* Initialize COM port "dev" */
int
com_init(dev)
int16 dev;
{
if (com[dev].drtype != 0){ /* port already in use? */
printf("COM%d: already in use\n",dev + 1);
return 1;
}
switch (combios(0x400,dev)) /* Probe driver & INIT (FOSSIL) */
{
case 0x1954: /* FOSSIL */
com[dev].drtype = 3; /* remember it is FOSSIL */
combios(0x0ff0,dev); /* set flowctrl (off for now) */
combios(0x1000,dev); /* ^C/^K checks OFF */
break;
case 0xaa55: /* COMBIOS/MBBIOS */
com[dev].drtype = 2; /* remember it is MBBIOS */
combios(0x0901,dev); /* set options (flow off for now) */
break;
default:
com[dev].drtype = 1; /* unknown type of driver */
printf("Warning: no COMBIOS/MBBIOS/FOSSIL loaded for COM%d\n",dev + 1);
break;
}
if (combios(0x00e3,dev) == 0x00e3) {
com[dev].drtype = 0;
printf("No BIOS support for COM%d\n",dev + 1);
return 1;
}
return 0;
}
/* Terminate COM port for "iface" */
int
com_stop(iface)
struct interface *iface;
{
combios(0x0000,iface->dev); /* set parameters 00 (=close) */
if (com[iface->dev].drtype == 3) /* if it is FOSSIL */
combios(0x0500,iface->dev); /* call it's uninit hook */
com[iface->dev].drtype = 0;
}
/* Asynchronous line I/O control */
com_ioctl(interface,argc,argv)
struct interface *interface;
int argc;
char *argv[];
{
if(argc < 2){
printf("%u %c\n",com[interface->dev].speed,
"nxh"[com[interface->dev].mode]);
return 0;
}
return com_speed(interface->dev,atoi(argv[0]),argv[1]);
}
/* Set asynch line speed */
int
com_speed(dev,speed,hands)
int16 dev;
unsigned speed;
char *hands;
{
unsigned char parm0,parm9; /* parameters for COMBIOS */
int i;
int mode;
for (mode = 2; mode >= 0; mode--)
if (*hands == "nxh"[mode])
break; /* set mode to 0 (none) 1 XON 2 hardw */
switch (com[dev].drtype) /* action depends on driver type */
{
case 1: /* unknown type, assume standard */
switch (speed)
{
case 300: parm0 = 0x43; break;
case 600: parm0 = 0x63; break;
case 1200: parm0 = 0x83; break;
case 2400: parm0 = 0xa3; break;
case 4800: parm0 = 0xc3; break;
case 9600: parm0 = 0xe3; break;
default:
printf(badspeed);
return 1;
}
combios((unsigned int) parm0,dev); /* set speed */
break;
case 2: /* COMBIOS/MBBIOS */
switch (speed)
{
case 300: parm0 = 0x43; parm9 = 0x00; break;
case 600: parm0 = 0x63; parm9 = 0x00; break;
case 1200: parm0 = 0x83; parm9 = 0x00; break;
case 2400: parm0 = 0xa3; parm9 = 0x00; break;
case 4800: parm0 = 0xc3; parm9 = 0x00; break;
case 9600: parm0 = 0xe3; parm9 = 0x00; break;
case 14400: parm0 = 0x23; parm9 = 0x20; break;
case 19200: parm0 = 0x43; parm9 = 0x20; break;
case 28800: parm0 = 0x63; parm9 = 0x20; break;
case 38400: parm0 = 0x83; parm9 = 0x20; break;
case 57600: parm0 = 0xa3; parm9 = 0x20; break;
case 115200: parm0 = 0xc3; parm9 = 0x20; break;
case 330400: parm0 = 0xe3; parm9 = 0x20; break;
default:
printf(badspeed);
return 1;
}
combios(0x0901 | parm9 | ((mode == 2)? 4 : 0),dev);
combios((unsigned int) parm0,dev);
if (com[dev].speed != speed) { /* speed change? */
com[dev].txbuf = 0;
for (i = 0; i < 5; i++) { /* send some chars */
if ((combios(0x0100 | FR_END,dev) & 0xa000) != 0x2000)
{ /* timeout or full */
com[dev].txbuf = speed / 100;
break; /* store chars for .1 s */
}
}
}
break;
case 3: /* FOSSIL */
switch (speed)
{
case 300: parm0 = 0x43; break;
case 600: parm0 = 0x63; break;
case 1200: parm0 = 0x83; break;
case 2400: parm0 = 0xa3; break;
case 4800: parm0 = 0xc3; break;
case 9600: parm0 = 0xe3; break;
case 19200: parm0 = 0x03; break;
case 38400: parm0 = 0x23; break;
default:
printf(badspeed);
return 1;
}
parm9 = 0xf0; /* calculate handshake parm */
if (mode == 1) /* XON/XOFF */
parm9 |= 9;
else
if (mode == 2) /* hardware (RTS/CTS) */
parm9 |= 2;
combios(0xf00 | parm9,dev); /* set handshake */
combios((unsigned int) parm0,dev); /* set speed */
break;
}
com[dev].mode = mode;
com[dev].speed = speed;
return 0;
}